﻿namespace RescueRaiders.Models
{
    using System.Collections.Generic;
    using System.Linq;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Graphics;

    /// <summary>
    /// The model factory.
    /// </summary>
    internal sealed class ModelFactory
    {
        /// <summary>
        /// The models.
        /// </summary>
        private readonly IList<BaseModel> models;

        /// <summary>
        /// Initializes static members of the <see cref="ModelFactory"/> class.
        /// </summary>
        static ModelFactory()
        {
            Instance = new ModelFactory();
        }

        /// <summary>
        /// Prevents a default instance of the <see cref="ModelFactory"/> class from being created.
        /// </summary>
        private ModelFactory()
        {
            models = new List<BaseModel>();
        }

        /// <summary>
        /// Gets Instance.
        /// </summary>
        public static ModelFactory Instance { get; private set; }

        /// <summary>
        /// The create aa gun.
        /// </summary>
        /// <param name="texture">
        /// The texture.
        /// </param>
        /// <param name="bulletTexture">
        /// The bullet texture.
        /// </param>
        /// <param name="position">
        /// The position.
        /// </param>
        /// <param name="side">
        /// The side.
        /// </param>
        /// <returns>
        /// </returns>
        public AAGun CreateAAGun(Texture2D texture, Texture2D bulletTexture, Vector2 position, Side side)
        {
            var enemy = models.Cast<HeliClass>().First(x => x.Side != side);
            var gun = new AAGun(texture, bulletTexture, position, side, enemy);
            models.Add(gun);
            return gun;
        }

        public Helipad CreateHelipad(Texture2D texture, Vector2 position, Side side)
        {
            var Helipad = new Helipad(texture, position, side);
            models.Add(Helipad);
            return Helipad;
        }

        /// <summary>
        /// The create helicopter.
        /// </summary>
        /// <param name="texture">
        /// The texture.
        /// </param>
        /// <param name="position">
        /// The position.
        /// </param>
        /// <param name="side">
        /// The side.
        /// </param>
        /// <returns>
        /// </returns>
        public HeliClass CreateHelicopter(Texture2D texture, Vector2 position, Side side)
        {
            var helicopter = new HeliClass(texture, position, side);
            models.Add(helicopter);
            return helicopter;
        }

        /// <summary>
        /// The draw.
        /// </summary>
        /// <param name="spriteBatch">
        /// The sprite batch.
        /// </param>
        /// <param name="cameraX">
        /// The camera x.
        /// </param>
        /// <param name="radartexture">
        /// The radartexture.
        /// </param>
        public void Draw(SpriteBatch spriteBatch, float cameraX, Texture2D radartexture)
        {
            foreach (var model in models)
            {
                model.Draw(spriteBatch, cameraX);
                model.Drawradar(spriteBatch, radartexture);
            }
        }

        /// <summary>
        /// The update.
        /// </summary>
        /// <param name="gameTime">
        /// The game time.
        /// </param>
        public void Update(Game1 game1, GameTime gameTime)
        {
            for (var i = 0; i < models.Count; ++i)
            {
                var model = models[i];
                model.Update(gameTime);
                for (var j = i + 1; j < models.Count; ++j)
                {
                    var model2 = models[j];
                    if (model.PosRectangle.Intersects(model2.PosRectangle))
                    {
                        var collisionPosition = model2.Collide(model);
                        if (!collisionPosition.Equals(Vector2.Zero))
                        {
                            game1.Addparticle(collisionPosition, model.frameSize.X, model2.frameSize.X);
                        }
                    }
                }
            }
        }
    }
}